using System;
using OracleInternal.Common;
using OracleInternal.ServiceObjects;

namespace OracleInternal.MTS
{
	internal class MTSTxnCtx
	{
		internal MTSTxnType m_txnType;

		internal string m_txnLocalID = string.Empty;

		internal OracleTransactionImpl m_localTxn;

		internal MTSTxnBranch m_mtsTxnBranch;

		private long m_connImplId;

		internal static MTSTxnCtx CreateMTSTxnCtx(OracleConnectionImpl connImpl)
		{
			return new CCPMTSTxnCtx();
		}

		internal MTSTxnCtx()
		{
			GC.SuppressFinalize(this);
		}

		internal virtual void SetCtx(OracleConnectionImpl connImpl)
		{
		}

		internal virtual void SetTxnState(bool bState)
		{
		}

		protected void Reset()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.MTSTxnCtx, OracleTraceFuncName.Reset, "MTSTxnCtx instance = " + GetHashCode() + " Local Txn = " + m_txnLocalID + "\t" + ((m_txnType == MTSTxnType.Distributed) ? ("Txn ID = " + m_mtsTxnBranch.TxnID?.ToString() + " using conn ID = " + m_connImplId) : string.Empty));
			}
			m_txnType = MTSTxnType.None;
			m_connImplId = 0L;
			m_localTxn = null;
			SetTxnState(bState: false);
		}

		internal virtual void Reset(OracleConnectionImpl connImpl)
		{
			Reset();
		}

		internal void SetLocalCtx(string txnLocalID, OracleTransactionImpl localTxn, long connImplId)
		{
			m_txnType = MTSTxnType.Local;
			m_txnLocalID = txnLocalID;
			m_localTxn = localTxn;
			m_connImplId = connImplId;
			SetTxnState(bState: true);
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.MTSTxnCtx, OracleTraceFuncName.SetLocalCtx, $"(Local Txn ID ={txnLocalID}) (sessid={connImplId}) (mtstxnctx={GetHashCode()})");
			}
		}

		internal void SetDistributedCtx(string txnLocalID, MTSTxnBranch mtsTxnBranch, long connImplId)
		{
			if (ProviderConfig.m_bTraceLevelPrivate_NoTrace)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)4352, OracleTraceClassName.MTSTxnCtx, OracleTraceFuncName.SetDistributedCtx, $"BEFORE (Old Txn Local ID ={m_txnLocalID}) (sessid={m_connImplId}) (mtstxnctx={GetHashCode()}) (Txn ID ={mtsTxnBranch.TxnID})");
			}
			m_txnType = MTSTxnType.Distributed;
			m_txnLocalID = txnLocalID;
			m_mtsTxnBranch = mtsTxnBranch;
			m_connImplId = connImplId;
			m_localTxn = null;
			SetTxnState(bState: true);
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.MTSTxnCtx, OracleTraceFuncName.SetDistributedCtx, $"(New Txn Local ID ={txnLocalID}) (sessid={connImplId}) (mtstxnctx={GetHashCode()}) (Txn ID ={mtsTxnBranch.TxnID})");
			}
		}

		internal void DelistTransaction(OracleConnectionImpl connImpl)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)4352, OracleTraceClassName.MTSTxnCtx, OracleTraceFuncName.DelistTransaction, "MTSTxnCtx instance = " + GetHashCode() + "\tTxn ID = " + ((m_mtsTxnBranch != null) ? m_mtsTxnBranch.TxnID.ToString() : "Null Txn") + " using conn ID = " + connImpl.m_endUserSessionId + " to DBInst = " + connImpl.m_instanceName);
			}
			try
			{
				if (m_mtsTxnBranch != null && m_txnType == MTSTxnType.Distributed)
				{
					m_mtsTxnBranch.Detach(connImpl);
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)4608, OracleTraceClassName.MTSTxnCtx, OracleTraceFuncName.DelistTransaction, "MTSTxnCtx instance = " + GetHashCode() + "\tTxn ID = " + ((m_mtsTxnBranch != null) ? m_mtsTxnBranch.TxnID.ToString() : "Null Txn") + " using conn ID = " + connImpl.m_endUserSessionId + " to DBInst = " + connImpl.m_instanceName);
				}
			}
		}
	}
}
